'''
Author: didiplus 
Date: 2023-08-31 10:25:32
LastEditors: didiplus 
LastEditTime: 2023-08-31 10:41:38
FilePath: \pythonscript\ping_tool.py
Description: 
Copyright (c) 2023 by didiplus, All Rights Reserved. 
'''
import threading
import pandas  as pd
import ping3



def single_ping(ip,timeout,ping_results):
    '''
    description: ping一个单独的IP地址
    :param ip: 要ping的IP地址
    :param timeout: ping的超时时间
    :param ping_results:  所有IPping的结果，字典格式，key是IP，value是ping的结果。    
    '''
    ping_time = ping3.ping(ip,timeout=timeout)
    ping_results[ip] = ping_time



def batch_ping(file="ping.xlsx",result_file="ping_result.xlsx",timeout=4):
    '''
    description: 从文件中读取待ping的列表，然后使用多线程批量去ping，结果再到一个表格文件中
    :param file: 待ping的表格文件
    :param timeout: 超时时间
    '''
    # 通过pandas读取ip列表
    df = pd.read_excel(file)
    ip_items = df.to_dict(orient='records')
    
    # 将字典的列表转换为字符串的列表
    ip_list = [ i['ip'] for i in ip_items]

    # 用于存储ping结果的字典
    ping_results = {}
    # 使用多线程进行批量的ping操作
    threads = []
    # 循环读取IP
    for ip in ip_list:
        # 将每个IP地址传、超时时间和存放结果的字典，通过多线程方式传给目标函数，创建一个线程
        t = threading.Thread(target=single_ping,args=(ip,timeout,ping_results))
        # 线程追加到线程池
        threads.append(t)
        # 启动此线程任务
        t.start()
    # 阻塞多线程任务，即当所有的线程执行完成后再继续主程序的余下部分代码
    for t in threads:
        t.join()
    
    # 将ping的结果再写会到原来的字典列表中去
    # 以从表格中读取到的字典列表作为数据源，以保证顺序一致
    for i in ip_items:
        # 根据 IP 地址获取其结果
        item_ping_result = ping_results[i['ip']]
        # 对情况进行判断，以文字的方式编写结果
        if item_ping_result is None:
            i['result'] = '超时失败'
        elif item_ping_result is False:
            i['result'] = '域名解析失败'
        else:
            i['result'] = '成功'
    # 极简表格操作法，写入表格
    new_df = pd.DataFrame(ip_items)
    new_df.to_excel(result_file,index=False,columns=['ip','result'])

if __name__ == '__main__':
    batch_ping()